// Copyright (C) 1953-2022 NUDT
// Verilog module name - announce_packet_generate
// Version: V4.1.0.20221208
// Created:
//         by - fenglin
////////////////////////////////////////////////////////////////////////////
// Description:
//         
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module announce_packet_generate#(parameter local_module_id = 12'd0)
(
    i_clk  ,
    i_rst_n,
	
	i_announce_generate_pulse,
	iv_hcp_mid               ,
  
	ov_data                               ,
	o_data_wr                             ,
    ov_ptp_message_type                   ,
    o_first_byte_valid                     
);

// I/O
// clk & rst
input                   i_clk  ;
input                   i_rst_n; 
// pkt input            						          
input	                i_announce_generate_pulse                         ;
input     [11:0]        iv_hcp_mid     ;
// pkt output to NMA
output reg [8:0]	    ov_data        ;
output reg	            o_data_wr      ;
output reg [3:0]        ov_ptp_message_type   ;
output reg              o_first_byte_valid    ;
//***************************************************
//               packet process
//***************************************************
reg       [15:0]              rv_announce_sequence        ;

reg       [7:0]               rv_byte_cnt            ;
reg       [1:0]               rv_apg_state           ;
localparam      IDLE_S                        = 2'd0,
                GENERATE_ANNOUNCE_S           = 2'd1;
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n)begin
        rv_announce_sequence    <= 16'b0;
		rv_byte_cnt              <= 8'b0 ;

		ov_data                  <= 9'b0 ;
        o_data_wr                <= 1'b0 ;
        ov_ptp_message_type      <= 4'b0 ;
        o_first_byte_valid       <= 1'b0 ;
                                 
        rv_apg_state             <= IDLE_S;        
    end
    else begin
        case(rv_apg_state)
            IDLE_S:begin			
				rv_byte_cnt         <= 8'b0 ;
				
				ov_data             <= 9'b0;
				o_data_wr           <= 1'b0;
                ov_ptp_message_type <= 4'hb ;
                o_first_byte_valid  <= 1'b0 ;                
				if(i_announce_generate_pulse)begin//
					rv_announce_sequence  <= rv_announce_sequence + 1'b1;
                    rv_apg_state           <= GENERATE_ANNOUNCE_S;                    
				end
				else begin
					rv_apg_state    <= IDLE_S;  
				end                    
            end
            GENERATE_ANNOUNCE_S:begin           
                rv_byte_cnt         <= rv_byte_cnt + 1'b1;				
				o_data_wr           <= 1'b1;
				case(rv_byte_cnt)
				    //dmac
				    8'd0:begin
                        ov_data             <= {1'b1,8'h01};
                        o_first_byte_valid  <= 1'b1 ; 
                    end
                    8'd1:begin
                        ov_data             <= {1'b0,8'h80};
                        o_first_byte_valid  <= 1'b0 ; 
                    end
					8'd2:ov_data          <= {1'b0,8'hC2};
					8'd3:ov_data          <= {1'b0,8'h00};
					8'd4:ov_data          <= {1'b0,8'h00};
					8'd5:ov_data          <= {1'b0,8'h0E};
					//smac                
					8'd6:ov_data          <= {1'b0, 8'h66                                 };
					8'd7:ov_data          <= {1'b0, 8'h26                                 };
					8'd8:ov_data          <= {1'b0, 8'h62                                 };
					8'd9:ov_data          <= {1'b0, iv_hcp_mid[11:4]                      };
					8'd10:ov_data         <= {1'b0, iv_hcp_mid[3:0 ],local_module_id[11:8]};
					8'd11:ov_data         <= {1'b0, local_module_id[7:0  ]                };
					//eth type
					8'd12:ov_data         <= {1'b0,8'h88};
					8'd13:ov_data         <= {1'b0,8'hF7};
					//majorSdoId,messageType
					8'd14:ov_data         <= {1'b0,4'h1,4'hb};
					//minorVersionPTP,versionPTP
					8'd15:ov_data         <= {1'b0,4'h0,4'h2};
					//messageLength
					8'd16:ov_data         <= {1'b0,8'h00};
					8'd17:ov_data         <= {1'b0,8'h4c};
					//domainNumber
					8'd18:ov_data         <= {1'b0,8'h00};
					//minorSdoId
					8'd19:ov_data         <= {1'b0,8'h00};
					//Flags
					8'd20:ov_data         <= {1'b0,8'h00};
					8'd21:ov_data         <= {1'b0,8'h0c};
					//correctionField
					8'd22:ov_data         <= {1'b0,8'h00};
					8'd23:ov_data         <= {1'b0,8'h00};
					8'd24:ov_data         <= {1'b0,8'h00};
					8'd25:ov_data         <= {1'b0,8'h00};
					8'd26:ov_data         <= {1'b0,8'h00};
					8'd27:ov_data         <= {1'b0,8'h00};
					8'd28:ov_data         <= {1'b0,8'h00};
					8'd29:ov_data         <= {1'b0,8'h00};
					//messageTypeSpecific
					8'd30:ov_data         <= {1'b0,8'h00};
					8'd31:ov_data         <= {1'b0,8'h00};
					8'd32:ov_data         <= {1'b0,8'h00};
					8'd33:ov_data         <= {1'b0,8'h00};
					//SourcePortIdentity
                    8'd34:ov_data         <= {1'b0,8'h66 };
					8'd35:ov_data         <= {1'b0,8'h26 };
					8'd36:ov_data         <= {1'b0,8'h62 };
					8'd37:ov_data         <= {1'b0,8'hFF};
					8'd38:ov_data         <= {1'b0,8'hFE};
					8'd39:ov_data         <= {1'b0,iv_hcp_mid[11:4]                      };
					8'd40:ov_data         <= {1'b0,iv_hcp_mid[3:0 ],local_module_id[11:8]};
					8'd41:ov_data         <= {1'b0,local_module_id[7:0  ]                };
					8'd42:ov_data         <= {1'b0,8'h00};
					8'd43:ov_data         <= {1'b0,8'h00};
					//sequenceId
                    8'd44:ov_data         <= {1'b0,rv_announce_sequence[15:8]};
					8'd45:ov_data         <= {1'b0,rv_announce_sequence[7:0] };
                    //controlField
					8'd46:ov_data         <= {1'b0,8'h05};
					//logMessageInterval
					8'd47:ov_data         <= {1'b0,8'h00};
	                //reserve
					8'd48:ov_data         <= {1'b0,8'h00};
					8'd49:ov_data         <= {1'b0,8'h00};
					8'd50:ov_data         <= {1'b0,8'h00};
					8'd51:ov_data         <= {1'b0,8'h00};
					8'd52:ov_data         <= {1'b0,8'h00};
					8'd53:ov_data         <= {1'b0,8'h00};
					8'd54:ov_data         <= {1'b0,8'h00};
					8'd55:ov_data         <= {1'b0,8'h00};
					8'd56:ov_data         <= {1'b0,8'h00};
					8'd57:ov_data         <= {1'b0,8'h00};
					//currentUtcOffset
					8'd58:ov_data         <= {1'b0,8'h00};
					8'd59:ov_data         <= {1'b0,8'h25};
					//reserved
					8'd60:ov_data         <= {1'b0,8'h00};
                    //grandmasterPriority1
					8'd61:ov_data         <= {1'b0,8'h80};
					//grandmasterClockQuality
					8'd62:ov_data         <= {1'b0,8'hF8};
					8'd63:ov_data         <= {1'b0,8'h23};
					8'd64:ov_data         <= {1'b0,8'hFF};
					8'd65:ov_data         <= {1'b0,8'hFF};
                    //grandmasterPriority2
					8'd66:ov_data         <= {1'b0,8'h80};
                    //grandmasterIdentity
					8'd67:ov_data         <= {1'b0,8'h66 };
					8'd68:ov_data         <= {1'b0,8'h26 };
					8'd69:ov_data         <= {1'b0,8'h62 };
					8'd70:ov_data         <= {1'b0,8'hFF};
					8'd71:ov_data         <= {1'b0,8'hFE};
					8'd72:ov_data         <= {1'b0,iv_hcp_mid[11:4]                      };
					8'd73:ov_data         <= {1'b0,iv_hcp_mid[3:0 ],local_module_id[11:8]};
					8'd74:ov_data         <= {1'b0,local_module_id[7:0  ]                };
                    //stepsRemoved
					8'd75:ov_data         <= {1'b0,8'h00};
                    8'd76:ov_data         <= {1'b0,8'h00};
                    //timeSource
                    8'd77:ov_data         <= {1'b0,8'hA0};
                    //path trace TLV
                    8'd78:ov_data         <= {1'b0,8'h00};
                    8'd79:ov_data         <= {1'b0,8'h08};
                    8'd80:ov_data         <= {1'b0,8'h00};
                    8'd81:ov_data         <= {1'b0,8'h08};
                    8'd82:ov_data         <= {1'b0,8'h66 };
                    8'd83:ov_data         <= {1'b0,8'h26 };
                    8'd84:ov_data         <= {1'b0,8'h62 };
                    8'd85:ov_data         <= {1'b0,8'hFF};
                    8'd86:ov_data         <= {1'b0,8'hFE};
                    8'd87:ov_data         <= {1'b0,iv_hcp_mid[11:4]                      };
                    8'd88:ov_data         <= {1'b0,iv_hcp_mid[3:0 ],local_module_id[11:8]};
					8'd89:begin
					    ov_data         <= {1'b1,local_module_id[7:0  ]                }; 
						rv_apg_state    <= IDLE_S;
				    end  
                endcase
            end	            
            default:begin
                ov_data             <= 9'b0;
				o_data_wr           <= 1'b0;
                ov_ptp_message_type <= 4'h0;
                o_first_byte_valid  <= 1'b0 ;               
                rv_byte_cnt         <= 8'b0 ;
				rv_apg_state        <= IDLE_S;  
            end
        endcase
    end
end
endmodule